<template>
  <a-drawer
    :width="520"
    :title="typeMap[operateType]"
    :placement="placement"
    :visible="visible"
    @close="onClose"
  >
    <template #extra>
      <a-space :size="8">
        <a-button @click="onClose" v-if="operateType != 'view'">
          <template #icon>
            <i class="s-icon iconfont icon-cancel" />
          </template>
          {{ t("base.cancel") }}
        </a-button>
        <a-button
          class="s-button"
          :loading="okLoading"
          type="primary"
          :disabled="drawer_disable_ok_button"
          @click="onFinish"
        >
          <template #icon>
            <i
              class="s-icon iconfont icon-tubiao_tijiao"
              style="height: auto"
            />
          </template>
          {{ operateType === "view" ? t("base.ok") : t("base.save") }}
        </a-button>
      </a-space>
    </template>
    <template #default>
      <a-form
        ref="formValidate"
        :model="formInline"
        layout="vertical"
        labelAlign="right"
        autocomplete="off"
      >
        <s-title>{{ t("base.baseInfo") }}</s-title>
        <a-form-item
          :label="t('table2') + ':'"
          name="mobile_number"
          :help="helpRef"
          :rules="[
            {
              required: true,
              trigger: ['change'],
              validator: validatorMobile,
            },
          ]"
        >
          <a-input
            v-model:value="formInline.mobile_number"
            v-input.trim.textFilter
            :placeholder="t('placeholder32')"
            allowClear
            v-input.num
            :maxlength="11"
          >
            <template v-slot:addonBefore>
              <a-select
                allowClear
                v-model:value="formInline.mobile_area"
                style="min-width: 120px"
                :placeholder="t('placeholder31')"
                :options="countryCodeOptions"
                @Select="onSelect"
                :showSearch="true"
                :filterOption="filterOption"
              />
            </template>
          </a-input>
        </a-form-item>

        <a-form-item
          :label="t('table189')"
          name="username"
          :rules="[{ required: true, message: t('placeholder125') }]"
        >
          <a-input
            v-model:value="formInline.username"
            v-input.trim.textFilter
            :placeholder="t('placeholder125')"
            :maxlength="12"
          />
        </a-form-item>

        <a-form-item
          :label="t('table192') + ':'"
          name="name"
          :rules="[{ required: true, message: t('placeholder126') }]"
        >
          <a-input
            v-model:value="formInline.name"
            v-input.trim.textFilter
            :placeholder="t('placeholder126')"
          >
          </a-input>
        </a-form-item>
        <a-form-item name="image" :label="t('table81')">
          <upload-image v-model="formInline.image" />
        </a-form-item>
        <a-form-item :label="t('table193')" name="desc">
          <a-textarea
            v-model:value="formInline.desc"
            v-input.textFilter
            :placeholder="t('placeholder124')"
            :rows="3"
            :maxlength="100"
            showCount
          />
        </a-form-item>

        <a-form-item
          :label="t('table31')"
          name="status"
          :rules="[{ required: true, message: t('placeholder61') }]"
        >
          <a-radio-group v-model:value="formInline.status">
            <a-radio :value="0">{{ t("sysAccount24") }}</a-radio>
            <a-radio :value="1">{{ t("sysAccount25") }}</a-radio>
          </a-radio-group>
        </a-form-item>

        <a-form-item
          v-if="operateType === 'add'"
          :label="t('sysAccount7')"
          name="password"
          :rules="[
            { required: true, validator: password_validate, trigger: 'change' },
          ]"
        >
          <a-input-password
            :maxlength="13"
            v-model:value="formInline.password"
            v-input.trim.textFilter
            :placeholder="t('placeholder16')"
          >
            <template #prefix>
              <LockOutlined style="color: rgba(0, 0, 0, 0.25)" />
            </template>
          </a-input-password>
        </a-form-item>
        <a-form-item
          v-if="operateType === 'add'"
          :label="t('sysAccount8')"
          name="confirm_password"
          :rules="[
            {
              required: true,
              validator: password_new_confirm_validate,
              trigger: 'change',
            },
          ]"
        >
          <a-input-password
            :maxlength="13"
            v-model:value="formInline.confirm_password"
            v-input.trim.textFilter
            :placeholder="t('placeholder1')"
          >
            <template #prefix>
              <LockOutlined style="color: rgba(0, 0, 0, 0.25)" />
            </template>
          </a-input-password>
        </a-form-item>

        <s-title>{{ t("base.roleManage") }}</s-title>
        <div class="Grid mb16">
          <div
            :class="[
              'grid-item',
              formInline.role_id === item.value ? 'active' : '',
            ]"
            v-for="(item, index) in roleOptions"
            :key="index"
            @click="onSelectRole($event, item, index)"
          >
            <div class="label">
              <td>{{ item.label }}</td>
              <td><i class="s-icon iconfont icon-beizhu" /></td>
            </div>
            <div class="desc">
              <!-- 写法1 -->
              <!-- <im-tooltip
                :value="item.desc"
                style="justify-content: flex-start"
                :length="8"
              /> -->
              <!-- 写法2 -->
              <render-tool-tip
                :value="item.desc"
                style="justify-content: flex-start"
                :length="8"
              />
            </div>
          </div>
        </div>
      </a-form>
    </template>
  </a-drawer>
</template>
<script lang="tsx">
import { DrawerProps } from "ant-design-vue";
import { RuleObject } from "ant-design-vue/lib/form";
import {
  countryCodeOptions,
  formInline,
  helpRef,
  operateType,
  tableLoading,
  addLoading,
  drawerInputValidators,
  set_formInline,
} from "../../store";
import { fetchCountryCodeOptions, validatorMobile } from "../../utils";
import { meassageMap } from "@userList/utils";
const formValidate: any = ref(null);
let password_validate = async (rule: RuleObject, value: string) => {
  if (isEmptyType(value)) {
    drawerInputValidators[1] = true;
    return Promise.reject($t("sysAccount12"));
  }
  if (isPassword(value)) {
    drawerInputValidators[1] = false;
    return Promise.resolve();
  } else {
    drawerInputValidators[1] = true;
    return Promise.reject($t("placeholder13"));
  }
};

let password_new_confirm_validate = async (rule: RuleObject, value: string) => {
  if (isEmptyType(value)) {
    drawerInputValidators[2] = true;
    return Promise.reject($t("placeholder0"));
  }
  if (value !== formInline.password) {
    drawerInputValidators[2] = true;
    return Promise.reject($t("placeholder13"));
  }

  if (value === formInline.confirm_password) {
    formValidate.value.clearValidate(["confirm_password"]);
  }
  if (isPassword(value)) {
    drawerInputValidators[2] = false;
    return Promise.resolve();
  } else {
    drawerInputValidators[2] = true;
    return Promise.reject($t("placeholder13"));
  }
};

export default defineComponent({
  props: {
    roleOptions: {
      type: Array<any>,
      required: true,
    },
  },
  components: {
    renderToolTip,
  },
  setup(props, { slots, expose, emit, attrs }: any) {
    const okLoading = ref(false);
    const drawer_disable_ok_button = computed(() => {
      if (operateType.value === "add") {
        return (
          isEmptyType(formInline.username) ||
          isEmptyType(formInline.name) ||
          isEmptyType(formInline.mobile_area) ||
          isEmptyType(formInline.mobile_number) ||
          isEmptyType(formInline.status) ||
          isEmptyType(formInline.password) ||
          isEmptyType(formInline.confirm_password) ||
          drawerInputValidators.some((bool) => bool === true)
        );
      }

      if (operateType.value === "edit") {
        return (
          isEmptyType(formInline.username) ||
          isEmptyType(formInline.name) ||
          isEmptyType(formInline.mobile_area) ||
          isEmptyType(formInline.mobile_number) ||
          isEmptyType(formInline.status) ||
          drawerInputValidators.some((bool) => bool === true)
        );
      }
    });
    const placement = ref<DrawerProps["placement"]>("right");
    const visible = ref<boolean>(false);
    const typeMap = reactive<any>({
      edit: getProxyT("sysAccount16"),
      add: getProxyT("sysAccount17"),
    });
    const showDrawer = async (type: string, record: any) => {
      if (type === "edit" && record) tableLoading.value = true;
      if (type === "add") addLoading.value = true;
      await fetchCountryCodeOptions();
      if (type === "edit" && record) tableLoading.value = false;
      if (type === "add") addLoading.value = false;
      visible.value = true;
      operateType.value = type;
      set_formInline(type, formInline, record);
    };
    expose({ showDrawer });
    const onClose = () => (visible.value = false);
    const defineApiMap = (string, formInline) => {
      const addAccount = async () =>
        await accountApi.create({
          username: formInline.username,
          role_id: formInline.role_id,
          name: formInline.name,
          mobile_number: formInline.mobile_number,
          mobile_area: formInline.mobile_area,
          status: formInline.status,
          image: formInline.image,
          desc: formInline.desc,
          password: formInline.password,
          confirm_password: formInline.confirm_password,
        });
      const updateAccount = async () =>
        await accountApi.update({
          id: formInline.id,
          username: formInline.username,
          role_id: formInline.role_id,
          name: formInline.name,
          mobile_number: formInline.mobile_number,
          mobile_area: formInline.mobile_area,
          status: formInline.status,
          image: formInline.image,
          desc: formInline.desc,
        });
      const apiMap = new Map([
        ["add", addAccount],
        ["edit", updateAccount],
      ]);
      return new Map([[/^[a-zA-Z_]*$/, apiMap.get(string)]]);
    };
    const handleApiTask = async () => {
      try {
        const string = operateType.value;
        const [, api]: any = [...defineApiMap(string, formInline)].find(
          ([key]) => key.test(string)
        );
        okLoading.value = true;
        const result: any = await api(formInline);
        if (result.code != 200) return message.error(result.message);
        visible.value = false;
        const [, showMessage] = [
          ...meassageMap(
            () => emit("refreshTable"),
            () => emit("fetchList")
          ),
        ].find(([key]) => key.test(string));
        showMessage();
      } catch (e: any) {
        message.error(e.message);
      } finally {
        okLoading.value = false;
      }
    };
    const onFinish = async () => handleApiTask();
    watch(
      () => visible.value,
      (newState) => {
        if (newState === false) {
          formValidate.value.clearValidate();
          clearObjAttr(formInline);
        }
      }
    );
    const onSelect = (value: any, option: any) => {
      validatorMobile(null, formInline.mobile_number);
    };
    const onSelectRole = (event: any, item: any, index: any) => {
      if (formInline.role_id === item.value) {
        formInline.role_id = undefined;
      } else {
        formInline.role_id = item.value;
      }
    };

    const handleClose = () => {
      formInline.image = "";
    };
    return {
      t: $t,
      handleClose,
      onSelectRole,
      helpRef,
      validatorMobile,
      objectToOptions,
      countryCodeOptions,
      onSelect,
      drawer_disable_ok_button,
      tableLoading,
      okLoading,
      operateType,
      typeMap,
      onFinish,
      formValidate,
      formInline,
      placement,
      visible,
      showDrawer,
      onClose,
      password_validate,
      password_new_confirm_validate,
    };
  },
});
</script>

<style lang="less" scoped>
.Grid {
  display: flex;
  flex-wrap: wrap;
  width: 100%;
  column-gap: calc((100% - (100% / 3.5) * 3) / 2);
  row-gap: 10px;

  .grid-item {
    background-color: #f0f0f0;
    width: calc(100% / 3.5);
    border-radius: 4px;
    padding: 10px;
    cursor: pointer;

    &.active {
      box-sizing: border-box;
      border: 1px solid red;
    }

    .label {
      display: flex;
      align-items: center;
      column-gap: 8px;

      td {
        &:first-of-type {
          font-size: 12px;
          font-weight: bold;
        }
      }
    }

    .desc {
      font-size: 12px;
    }
  }
}
</style>
